import './index.scss'
import {FC, memo, useMemo} from "react";
import containerAtom, {VisualEditorBlockData} from "../atoms/container.atom";
import {useRecoilState, useSetRecoilState} from "recoil";

import {Button, Form, Input, InputNumber, Select,} from 'antd';
import {SelectOption, VisualEditorProps, VisualEditorPropsType} from "../../utils/createEditorProp";
import {replaceItemWithCompare} from "../../store/utils";

interface PropsType {
    selectedBlock?: VisualEditorBlockData;
}

const Operator: FC<PropsType> = memo((props) => {
    const {selectedBlock} = props
    const [containerStyle, setContainerProps] = useRecoilState(containerAtom.containerAtom)
    const setBlocks = useSetRecoilState(containerAtom.blocksAtom)

    const [formInstance] = Form.useForm()
    const computedTypeComponent = useMemo(() => {
        return (type: VisualEditorPropsType, index: number, options?: SelectOption[]) => {
            switch (type) {
                case VisualEditorPropsType.input:
                    return <Input/>
                case VisualEditorPropsType.select:
                    return <Select>
                        {options?.map((option, inx) => <Select.Option
                            key={inx}
                            value={option.value}>
                            {option.label}
                        </Select.Option>)}
                    </Select>
                case VisualEditorPropsType.color:
                    return <div key={index}>颜色选择</div>
            }
        }
    }, [])
    const operatorRender = useMemo(() => {
        return () => {
            if (selectedBlock) {
                if (!!selectedBlock.props) {
                    return <>{
                        Object.entries(selectedBlock.props).map(([key, value], index) => {
                            return <Form.Item
                                key={index}
                                label={value.label}
                                name={key}
                            >
                                {computedTypeComponent(value.type, index, value.selectOptions,)}
                            </Form.Item>
                        })
                    }</>
                }

            } else {
                return <>
                    <Form.Item
                        label="容器宽度"
                        name="width"
                    >
                        <InputNumber/>
                    </Form.Item>
                    <Form.Item
                        label="容器高度"
                        name="height"
                    >
                        <InputNumber/>
                    </Form.Item>
                </>
            }

        }

    }, [selectedBlock])

    const apply = useMemo(() => {
        return () => {
            const props = formInstance.getFieldsValue()

            if (selectedBlock) {
                let newProps: Record<string, any> = {}
                if (selectedBlock && selectedBlock.props) {
                    Object.entries(selectedBlock.props).forEach(([key, value]) => {
                        newProps[key] = {
                            ...value,
                            value: props[key]
                        }
                    })
                }
                setBlocks(blocks => {
                    const newValue = replaceItemWithCompare(blocks, (block) => {
                        return block.no == selectedBlock.no
                    }, {
                        ...selectedBlock,
                        props: {
                            ...selectedBlock.props,
                            ...newProps
                        }
                    })
                    return newValue
                })

            } else {
                setContainerProps((value) => {
                    return {
                        ...value,
                        style: {
                            ...value.style,
                            ...props
                        }
                    }
                })
            }
        }
    }, [selectedBlock, formInstance])

    const reset = useMemo(() => {
        return () => {
            formInstance.resetFields()
        }
    }, [formInstance])


    const computedSelectedBlockInitialValues = useMemo(() => {
        if (!selectedBlock || !selectedBlock.props) {
            return {}
        }
        const res = Object.keys(selectedBlock.props).reduce<Record<string, any>>((memo, key) => {
            const props = selectedBlock.props
            if (key && selectedBlock && props && props[key]) {
                memo[key] = props[key].value
            }
            return memo

        }, {})
        formInstance.setFieldsValue(res)
        return res
    }, [selectedBlock])

    return <div className="visual-editor-operator">
        <div className="visual-editor-operator-title"> {selectedBlock ? '编辑组件' : '编辑容器'}</div>
        <div className="visual-editor-operator-form">
            <Form
                name="basic"
                form={formInstance}
                initialValues={selectedBlock ? computedSelectedBlockInitialValues : {...containerStyle.style}}
            >
                {operatorRender()}
            </Form>
        </div>
        <div className="visual-editor-operator-handle">
            <Button
                size="small"
                type="primary"
                onClick={() => apply()}
            >应用</Button>
            <Button
                size="small"
                onClick={() => reset()}
            >重置</Button>
        </div>
    </div>
})

export default Operator
